﻿using QFramework;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;

namespace HKTools
{
    public interface IHK_TcpServerSystem : ISystem
    {
        bool IsServerRunning { get; set; }

        /// <summary>
        /// 连接的Client端列表
        /// </summary>
        List<Socket> RemoteClients { get; set; }

        /// <summary>
        /// 连接的Client端Ip和端口号列表
        /// </summary>
        List<string> RemoteClientsIP { get; set; }

        /// <summary>
        /// Server端 开启
        /// </summary>
        void ServerStart();

        /// <summary>
        /// Server端 关闭
        /// </summary>
        void ServerClose();

        /// <summary>
        /// Server端 给 所有Client端，发送消息
        /// </summary>
        /// <param name="msg"></param>
        void SendMsg_ServerToAllClients(string msg);

        /// <summary>
        /// 通过 IP 和 端口号，Server端 给 Client端，发送消息
        /// </summary>
        /// <param name="ipAndPort"></param>
        /// <param name="msg"></param>
        void SendMsg_ServerToClient(string ipAndPort, string msg);

        /// <summary>
        /// 通过 Socket，Server端 给 Client端，发送消息
        /// </summary>
        /// <param name="ipAndPort"></param>
        /// <param name="msg"></param>
        void SendMsg_ServerToClient(Socket remoteSocket, string msg);

        /// <summary>
        /// 设置是否开启 系统层Debug
        /// </summary>
        /// <param name="isOn"></param>
        void SetDebugState(bool isOn);
    }

    public class HK_TcpServerSystem : AbstractSystem, IHK_TcpServerSystem
    {
        public bool IsServerRunning { get; set; }
        public List<Socket> RemoteClients { get; set; }
        public List<string> RemoteClientsIP { get; set; }

        Thread serverThread;
        CancellationTokenSource ctsServer; // 使用CancellationTokenSource替代Thread.Abort

        Socket serverSocket;

        SynchronizationContext mainThreadContext;

        bool isDebugOn = false;

        protected override void OnInit()
        {
            IsServerRunning = false;
            mainThreadContext = SynchronizationContext.Current;
            RemoteClients = new List<Socket>(); // 初始化客户端列表
            RemoteClientsIP = new List<string>(); // 初始化客户端 IP 和 端口号 列表

            // Server端 系统层不进行Debug打印
            SetDebugState(false);
        }

        public void ServerStart()
        {
            if (IsServerRunning)
            {
                Debug.LogWarning("Server端已经启动，不能重复启动！");
                return;
            }

            ctsServer = new CancellationTokenSource();

            serverThread = new Thread(() => ServerStart_ThreadMethod(ctsServer.Token))
            {
                IsBackground = true
            };
            serverThread.Start();
        }

        void ServerStart_ThreadMethod(CancellationToken token)
        {
            try
            {
                serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 8080);
                serverSocket.Bind(ipEndPoint);
                serverSocket.Listen(1024);
                HKDebug.Log("Server端 开启，等待客户端连接...", LogColor.Blue);

                IsServerRunning = true;

                while (!token.IsCancellationRequested)
                {
                    if (serverSocket.Poll(1000, SelectMode.SelectRead))
                    {
                        Socket remoteClient = serverSocket.Accept();
                        IPEndPoint remoteEndPoint = (IPEndPoint)remoteClient.RemoteEndPoint;

                        RemoteClients.Add(remoteClient); // 添加新客户端到列表
                        RemoteClientsIP.Add($"{remoteEndPoint.Address}:{remoteEndPoint.Port}");

                        if (isDebugOn)
                            HKDebug.Log($"Client({remoteEndPoint.Address}:{remoteEndPoint.Port}) 连接成功!", LogColor.Blue);

                        this.SendEvent(new Event_ClientConnect() { _address = remoteEndPoint.Address.ToString(), _port = remoteEndPoint.Port });

                        Thread clientThread = new Thread(() => HandleClient_ThreadMethod(remoteClient, remoteEndPoint, token))
                        {
                            IsBackground = true
                        };

                        clientThread.Start();
                    }
                }
            }
            catch (SocketException e)
            {
                Debug.LogError(e.Message);
            }
        }

        void HandleClient_ThreadMethod(Socket remoteClient, IPEndPoint remoteEndPoint, CancellationToken token)
        {
            try
            {
                remoteClient.Send(Encoding.UTF8.GetBytes("欢迎连入服务器..."));

                while (!token.IsCancellationRequested)
                {
                    if (remoteClient.Available <= 0)
                    {
                        Thread.Sleep(10); // 避免忙等待
                        continue;
                    }

                    // 接收客户端发送来的消息
                    byte[] msgBytes = new byte[1024];
                    int msgLength = remoteClient.Receive(msgBytes);

                    string clientMessage = Encoding.UTF8.GetString(msgBytes, 0, msgLength);

                    mainThreadContext.Post(_ =>
                    {
                        if (isDebugOn)
                            Debug.Log($"Client({remoteEndPoint.Address}:{remoteEndPoint.Port}) 消息：" + clientMessage);

                        this.SendEvent(new Event_FromClientMsg() { _address = remoteEndPoint.Address.ToString(), _port = remoteEndPoint.Port, _msg = clientMessage });

                        if (clientMessage.Trim().Equals("CLIENTCLOSE"))
                        {
                            if (isDebugOn)
                                HKDebug.Log($"Client({remoteEndPoint.Address}:{remoteEndPoint.Port}) 断开连接!", LogColor.Blue);

                            RemoteClients.Remove(remoteClient); // 从列表中移除Client
                            RemoteClientsIP.Remove($"{remoteEndPoint.Address}:{remoteEndPoint.Port}"); // 从列表中移除Client的Ip

                            this.SendEvent(new Event_ClientDisConnect() { _address = remoteEndPoint.Address.ToString(), _port = remoteEndPoint.Port });

                            remoteClient.Close(); // 关闭客户端连接
                        }
                    }, null);

                    if (clientMessage.Trim().Equals("CLIENTCLOSE"))
                    {
                        return;
                    }
                }
            }
            catch (SocketException e)
            {
                Debug.LogWarning("Client端 异常！");

                // 客户端断开连接
                mainThreadContext.Post(_ =>
                {
                    if (isDebugOn)
                        HKDebug.Log($"Client({remoteEndPoint.Address}:{remoteEndPoint.Port}) 断开连接!", LogColor.Blue);

                    RemoteClients.Remove(remoteClient); // 从列表中移除Client
                    RemoteClientsIP.Remove($"{remoteEndPoint.Address}:{remoteEndPoint.Port}"); // 从列表中移除Client的Ip

                    this.SendEvent(new Event_ClientDisConnect() { _address = remoteEndPoint.Address.ToString(), _port = remoteEndPoint.Port });

                    remoteClient.Close(); // 关闭客户端连接
                }, null);
            }
        }

        public void SendMsg_ServerToAllClients(string msg)
        {
            if (!IsServerRunning)
                return;

            foreach (var remoteClient in RemoteClients)
            {
                // 添加检查以确保Socket已连接
                if (remoteClient != null && remoteClient.Connected)
                {
                    remoteClient.Send(Encoding.UTF8.GetBytes(msg));
                }
            }
        }

        public void SendMsg_ServerToClient(string ipAndPort, string msg)
        {
            if (!IsServerRunning)
                return;

            int index = RemoteClientsIP.IndexOf(ipAndPort);
            if (index != -1)
            {
                Socket remoteClient = RemoteClients[index];
                if (remoteClient != null && remoteClient.Connected)
                {
                    remoteClient.Send(Encoding.UTF8.GetBytes(msg));
                }
            }
        }

        public void SendMsg_ServerToClient(Socket remoteSocket, string msg)
        {
            if (!IsServerRunning)
                return;

            if (remoteSocket != null && remoteSocket.Connected)
            {
                remoteSocket.Send(Encoding.UTF8.GetBytes(msg));
            }
        }

        public void ServerClose()
        {
            if (!IsServerRunning)
                return;

            SendMsg_ServerToAllClients("SERVERCLOSE");

            // 使用 CancellationTokenSource来通知停止线程
            ctsServer?.Cancel();

            lock (RemoteClients) // 加锁确保线程安全
            {
                foreach (var client in RemoteClients)
                {
                    if (client != null)
                    {
                        client.Shutdown(SocketShutdown.Both);
                        client.Close();
                    }
                }

                RemoteClients.Clear(); // 清空客户端列表
                RemoteClientsIP.Clear(); // 清空客户端IP列表
            }

            if (serverSocket != null)
            {
                serverSocket.Close();
                serverSocket = null;
            }

            CleanupThread(ref serverThread); // 使用方法来清理线程资源

            IsServerRunning = false;
            HKDebug.Log("Server端 关闭", LogColor.Red);
        }

        public void SetDebugState(bool isOn)
        {
            isDebugOn = isOn;
        }

        void CleanupThread(ref Thread thread)
        {
            if (thread != null && thread.IsAlive)
            {
                thread.Join(); // 等待线程优雅结束
            }
            thread = null;
        }
    }
}